﻿using System.Collections;
using UnityEngine;
using TMPro;
using UnityEngine.UI;

public class ZooUIController : MonoBehaviour
{
    public static ZooUIController instance;

    [Header("UI References")]
    [SerializeField] private Image nextButton;
    [SerializeField] private Image nextButton2;
    [SerializeField] private GameObject textPanel;
    [SerializeField] private GameObject notebookPanel;
    [SerializeField] private GameObject animalPanel;
    [SerializeField] private GameObject animalKiara;
    [SerializeField] private Image animalSprite;
    [SerializeField] private TMP_Text animalText;
    [SerializeField] private Image animalBackground;
    [SerializeField] private Animator canvasAnim;
    [SerializeField] private TMP_Text chatText;
    [SerializeField] private TMP_InputField inputField;

    [Header("Settings")]
    [SerializeField] private int step;

    private string originalAnimalInput = "";
    private string interpretedAnimalName = "";

    private bool canPressNext = true;



    private void Awake()
    {
        if (instance == null) instance = this;
        else Destroy(gameObject);
    }


    // ------------------------------
    // NEXT BUTTON + FLOW CONTROL
    // ------------------------------
    public void ShowTextPanel()
    {
        textPanel.SetActive(true);
        HideShowNextButton(true);
    }

    public void HideShowNextButton(bool show)
    {
        nextButton.gameObject.SetActive(show);
        nextButton2.gameObject.SetActive(show);
    }


    public void ContinueButton()
    {
        if (!canPressNext) return;

        step++;

        switch (step)
        {
            case 1:
                chatText.transform.parent.gameObject.SetActive(true);
                chatText.text = "I will be your guide today. What animal would you like to see?";
                ZooMusicManager.Instance.PlaySFX(0);
                break;

            case 2:
                chatText.transform.parent.gameObject.SetActive(false);
                inputField.gameObject.SetActive(true);
                ZooPlatformGenerator.instance.GenerateLevel();
                ZooMusicManager.Instance.PlaySFX(5);
                break;

            case 3:
                if (string.IsNullOrWhiteSpace(inputField.text))
                {
                    step--;
                    break;
                }

                originalAnimalInput = inputField.text.Trim().ToLower();

                // Validate and interpret the kid’s input
                StartCoroutine(ValidateAnimalName(originalAnimalInput));
                break;

            case 4:
                canvasAnim.SetTrigger("Animal");
                ZooMusicManager.Instance.PlaySFX(0);
                break;

            case 5:
                canvasAnim.SetTrigger("Details");
                animalPanel.SetActive(true);
                ZooMusicManager.Instance.PlaySFX(0);
                break;

            case 6:
                chatText.transform.parent.gameObject.SetActive(true);
                animalPanel.SetActive(false);
                animalSprite.gameObject.SetActive(false);
                chatText.text = "What animal would you like to see next?";
                canvasAnim.SetTrigger("Ask");
                inputField.text = "";
                ZooMusicManager.Instance.PlaySFX(5);
                break;

            case 7:
                step = 1;
                ContinueButton();
                break;

            case 8: // blocked invalid animal
                chatText.text = "In this zoo, we can only visit real animals.";
                BlockNextForSeconds(4);
                ZooMusicManager.Instance.PlaySFX(8);
                break;

            case 9:
                chatText.text = "Try again! Remember we may also visit previous animals by opening the notebook.";
                BlockNextForSeconds(4);
                ZooMusicManager.Instance.PlaySFX(0);
                break;

            case 10:
                step = 1;
                ContinueButton();
                break;
        }
    }


    private void BlockNextForSeconds(float seconds)
    {
        canPressNext = false;
        nextButton.color = Color.black;
        nextButton2.color = Color.black;
        Invoke(nameof(CanPressNext), seconds);
    }

    public void CanPressNext()
    {
        canPressNext = true;
        nextButton.color = Color.white;
        nextButton2.color = Color.white;
    }

    public void SplashScreenClick()
    {
        canvasAnim.SetTrigger("Start");
        ZooMusicManager.Instance.PlaySFX(6);
    }


    // ------------------------------
    // NOTEBOOK SUPPORT
    // ------------------------------
    public void OpenCloseNotebook()
    {
        ZooMusicManager.Instance.PlaySFX(3);
        if (notebookPanel.activeInHierarchy)
        {
            notebookPanel.SetActive(false);
            HideShowNextButton(true);
        }
        else
        {
            ZooNotebookUI.Instance.RefreshNotebook();
            notebookPanel.SetActive(true);
            HideShowNextButton(false);
        }
    }

    public void ShowAnimalFromNotebook(AnimalEntry entry)
    {
        interpretedAnimalName = entry.name;

        animalText.text = entry.info;
        animalSprite.sprite = entry.spriteAnimal;
        animalBackground.sprite = entry.spriteBackground;

        inputField.gameObject.SetActive(false);
        textPanel.SetActive(false);

        animalSprite.gameObject.SetActive(true);
        animalPanel.SetActive(true);

        HideShowNextButton(true);

        // Jump directly into animal view
        step = 4;
        canvasAnim.SetTrigger("NotebookPress");
    }



    // ------------------------------
    // AI VALIDATION & INTERPRETATION
    // ------------------------------
    private IEnumerator ValidateAnimalName(string kidWord)
    {
        // Local instant block for obvious fantasy creatures
        string[] bannedWords =
        {
            "dragon", "phoenix", "unicorn", "monster", "demon",
            "god", "alien", "fairy", "robot", "creature", "beast"
        };

        foreach (string banned in bannedWords)
        {
            if (kidWord.Contains(banned))
            {
                RejectInvalidAnimal();
                yield break;
            }
        }

        // The powerful LLM interpretation prompt
        string checkPrompt =
        $"A kid typed: '{kidWord}'. Your job: guess what REAL animal they meant.\n" +
        $"Fix spelling errors, vague categories, or descriptive phrases.\n\n" +
        $"Return **ONLY** one of these formats:\n" +
        $"1) YES: <specific real animal>\n" +
        $"2) NO\n\n" +
        $"Examples:\n" +
        $"'big cat' → YES: tiger\n" +
        $"'ppolar ber' → YES: polar bear\n" +
        $"'cute fish' → YES: goldfish\n" +
        $"'biggest bug' → YES: goliath beetle\n" +
        $"'fire unicorn' → NO\n\n" +
        $"Rules:\n" +
        $"- Pick ONE specific real existing animal.\n" +
        $"- Never fictional.\n" +
        $"- Only return: YES: ___  or  NO";

        bool done = false;
        bool isAnimal = false;
        string interpreted = "";

        LLMClient.Instance.SendSingleMessage("user", checkPrompt, reply =>
        {
            string clean = reply.Trim().ToLower();

            if (clean.StartsWith("yes:"))
            {
                isAnimal = true;
                interpreted = clean.Substring(4).Trim();
            }
            else
            {
                isAnimal = false;
            }

            done = true;
        });

        yield return new WaitUntil(() => done);

        if (!isAnimal)
        {
            RejectInvalidAnimal();
            yield break;
        }

        // SUCCESS: we have a real animal
        interpretedAnimalName = interpreted;

        // Continue the flow
        canvasAnim.SetTrigger("Platform");
        animalKiara.SetActive(false);
        inputField.gameObject.SetActive(false);

        StartCoroutine(RequestAnimalContent(interpretedAnimalName));
        Invoke(nameof(ResetPlayerPos), 0.5f);
    }


    private void RejectInvalidAnimal()
    {
        chatText.transform.parent.gameObject.SetActive(true);
        inputField.gameObject.SetActive(false);
        chatText.text = "Hahahaha, you are funny! That's not a real animal!";
        inputField.text = "";

        step = 7;
        BlockNextForSeconds(4);
    }



    // ------------------------------
    // ANIMAL CONTENT REQUESTS
    // ------------------------------
    public IEnumerator RequestAnimalContent(string realAnimalName)
    {
        yield return new WaitForEndOfFrame();

        // --- Ask for educational animal fact ---
        string infoPrompt =
            $"In 2–3 simple sentences, write a short, fun educational fact about the {realAnimalName}. " +
            $"Use very child-friendly language.";

        bool infoDone = false;
        string fact = "";

        LLMClient.Instance.SendSingleMessage("user", infoPrompt, reply =>
        {
            fact = reply.Trim();
            infoDone = true;
        });

        yield return new WaitUntil(() => infoDone);
        animalText.text = fact;


        // --- Ask for correct zoo-style habitat ---
        string habitatPrompt =
            $"Describe in 2–4 words the main realistic zoo enclosure suited for a {realAnimalName}. " +
            $"Water animals → aquarium-style habitats (example: 'coral reef tank'). " +
            $"Land animals → natural habitats (example: 'savanna enclosure'). " +
            $"Birds → aviary enclosure. Insects → terrarium enclosure.\n" +
            $"Return ONLY the habitat name.";

        bool habitatDone = false;
        string habitat = "";

        LLMClient.Instance.SendSingleMessage("user", habitatPrompt, reply =>
        {
            habitat = reply.Replace(".", "").Trim();
            habitatDone = true;
        });

        yield return new WaitUntil(() => habitatDone);


        // --- Generate images ---
        bool spriteDone = false;
        bool bgDone = false;

        string animalPrompt =
            $"A full-body, semi-realistic digital painting of a {realAnimalName}, natural lighting, PNG, transparent background, no text.";

        StartCoroutine(ImageGenerator.Instance.GenerateNpcImage(animalPrompt, sprite =>
        {
            animalSprite.sprite = sprite;
            spriteDone = true;
        }));


        string bgPrompt =
            $"A semi-realistic, clean zoo-style {habitat} habitat enclosure, perfect for a {realAnimalName}. " +
            $"No animals, no people, only scenery.";

        StartCoroutine(ImageGenerator.Instance.GenerateSceneImage(bgPrompt, tex =>
        {
            Sprite bgSprite = Sprite.Create(
                tex,
                new Rect(0, 0, tex.width, tex.height),
                Vector2.one * 0.5f
            );

            animalBackground.sprite = bgSprite;
            bgDone = true;
        }));


        yield return new WaitUntil(() => spriteDone && bgDone);

        // Reveal
        animalSprite.gameObject.SetActive(true);
        animalPanel.SetActive(true);
        canvasAnim.SetTrigger("RequestDone");
        ZooMusicManager.Instance.NextSong();

        // Save to notebook
        ZooNotebookManager.Instance.AddAnimal(
            realAnimalName,
            fact,
            animalSprite.sprite,
            animalBackground.sprite
        );
    }



    private void ResetPlayerPos()
    {
        ZooCharacterController.instance.ResetPos();
    }
}
